/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
 */

package com.huaweicloud.rds.sdk.demo;

import static java.util.Collections.singletonList;

import com.huaweicloud.sdk.core.auth.BasicCredentials;
import com.huaweicloud.sdk.core.auth.ICredential;
import com.huaweicloud.sdk.core.exception.ConnectionException;
import com.huaweicloud.sdk.core.exception.RequestTimeoutException;
import com.huaweicloud.sdk.core.exception.ServiceResponseException;
import com.huaweicloud.sdk.core.region.Region;
import com.huaweicloud.sdk.rds.v3.RdsClient;
import com.huaweicloud.sdk.rds.v3.model.AllowDbUserPrivilegeRequest;
import com.huaweicloud.sdk.rds.v3.model.AllowDbUserPrivilegeResponse;
import com.huaweicloud.sdk.rds.v3.model.CreateDatabaseRequest;
import com.huaweicloud.sdk.rds.v3.model.CreateDatabaseResponse;
import com.huaweicloud.sdk.rds.v3.model.DatabaseForCreation;
import com.huaweicloud.sdk.rds.v3.model.GrantRequest;
import com.huaweicloud.sdk.rds.v3.model.ListDatabasesRequest;
import com.huaweicloud.sdk.rds.v3.model.ListDatabasesResponse;
import com.huaweicloud.sdk.rds.v3.model.UserWithPrivilege;
import com.huaweicloud.sdk.rds.v3.region.RdsRegion;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * rds(mysql)数据库列表相关示例代码
 * 1、查看数据库列表
 * 2、创建数据库
 * 3、查看数据库列表
 * 4、授权数据库账号
 *
 * @since 2022-10-26
 */
public class MysqlDbDemo {
    private static final Logger logger = LoggerFactory.getLogger(MysqlDbDemo.class.getName());

    private static final Region REGION = RdsRegion.CN_EAST_3; // 实例所在的Region

    public static void main(String[] args) {
        String ak = args[0]; // "<YOUR AK>"
        String sk = args[1];  // "<YOUR SK>"
        String instanceId = "<YOUR INSTANCE_ID>";
        String dbName = "<YOUR DATABASE NAME>";
        String dbCharSet = "<YOUR DATABASE CHARSET>";
        String dbUser = "<YOUR DATABASE USER>";
        boolean dbUserReadOnly = false; // <YOUR DATABASE USER READONLY>;
        int page = 1; // <YOUR PAGE>
        int limit = 10; // <YOUR LIMIT>

        RdsClient client = createClient(ak, sk);
        // 查看数据库列表
        listDatabases(client, instanceId, page, limit);
        // 创建数据库
        createDatabase(client, instanceId, dbName, dbCharSet);
        // 查看数据库列表
        listDatabases(client, instanceId, page, limit);
        // 授权数据库账号
        allowDbUserPrivilege(client, instanceId, dbName, dbUser, dbUserReadOnly);
    }

    private static RdsClient createClient(String ak, String sk) {
        ICredential auth = new BasicCredentials().withAk(ak).withSk(sk);
        return RdsClient.newBuilder().withCredential(auth).withRegion(REGION).build();
    }

    private static void listDatabases(RdsClient client, String instanceId, int page, int limit) {
        ListDatabasesRequest request = new ListDatabasesRequest()
            .withInstanceId(instanceId)
            .withPage(page)
            .withLimit(limit);
        invokeClient(() -> {
            ListDatabasesResponse response = client.listDatabases(request);
            logger.info(response.toString());
        });
    }

    private static void createDatabase(RdsClient client, String instanceId, String name, String characterSet) {
        CreateDatabaseRequest request = new CreateDatabaseRequest()
            .withInstanceId(instanceId)
            .withBody(
                new DatabaseForCreation().withName(name).withCharacterSet(characterSet)
            );
        invokeClient(() -> {
            CreateDatabaseResponse response = client.createDatabase(request);
            logger.info(response.toString());
        });
    }

    private static void allowDbUserPrivilege(RdsClient client, String instanceId, String dbName, String userName,
        boolean readonly) {
        AllowDbUserPrivilegeRequest request = new AllowDbUserPrivilegeRequest()
            .withInstanceId(instanceId)
            .withBody(
                new GrantRequest()
                    .withDbName(dbName)
                    .withUsers(singletonList(new UserWithPrivilege().withName(userName).withReadonly(readonly)))
            );
        invokeClient(() -> {
            AllowDbUserPrivilegeResponse response = client.allowDbUserPrivilege(request);
            logger.info(response.toString());
        });
    }

    private static <T> void invokeClient(Runnable runnable) {
        try {
            runnable.run();
        } catch (ConnectionException e) {
            logger.error("ConnectionException", e);
        } catch (RequestTimeoutException e) {
            logger.error("RequestTimeoutException", e);
        } catch (ServiceResponseException e) {
            logger.error("httpStatusCode: {}, errorCode: {}, errorMsg: {}", e.getHttpStatusCode(), e.getErrorCode(),
                e.getErrorMsg());
        }
    }
}

